/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
#include <stdlib.h>
#include <iostream>

#include "profile/DefaultProfile.h"

using std::string;
using aliyun::regions::Endpoint;
using aliyun::regions::ProductDomain;
using aliyun::profile::IClientProfile;
using aliyun::profile::DefaultProfile;

#define assertTrue(expr) do { \
  std::cerr << "assertTrue(" << #expr << "): "; \
  if(expr) { \
    std::cerr << "PASS!" << std::endl; \
  } else { \
    std::cerr << "FAIL!" << std::endl; \
    ::exit(-1); \
  } \
} while(0)

void testProfileCredential() {
  IClientProfile* iprofile = DefaultProfile::getProfile("cn-beijing", "testid",
                                                        "testsecret");
  assertTrue("cn-beijing" == iprofile->getRegionId());
  assertTrue("testid" == iprofile->getCredential().getAccessKeyId());
  assertTrue("testsecret" == iprofile->getCredential().getAccessSecret());
}

void dumpEndpoint(const Endpoint& e) {
  std::cout << "=== " << e.getName() << " ===\n";
  for (auto& rid : e.getRegionIds()) {
    std::cout << rid << "\n";
  }
  for (auto& pd : e.getProductDomains()) {
    std::cout << pd.getDomainName() << "\t" << pd.getProductName() << "\n";
  }
  std::cout << std::endl;
}

void addToEndpointsTest() {
  DefaultProfile::getProfile()->getEndpoints();

  DefaultProfile::addToEndpoints("cn-hangzhou", "cn-hangzhou", "Ecs",
                                 "ecs.aliyun.com");
  DefaultProfile::addToEndpoints("cn-beijing", "cn-beijing", "Ecs",
                                 "ecs.aliyun.com");
  DefaultProfile::addToEndpoints("cn-shanghai", "cn-shanghai", "Ecs",
                                 "ecs.aliyun.com");

  std::vector<Endpoint> endpoints =
      DefaultProfile::getProfile()->getEndpoints();
  for (auto& e : endpoints) {
    dumpEndpoint(e);
  }
}

void addEndpointTest() {
  DefaultProfile::addEndpoint("cn-hangzhou", "cn-hangzhou", "Ecs",
                              "ecs.aliyun.com");
  DefaultProfile::addEndpoint("cn-hangzhou", "cn-beijing", "Ace",
                              "ace.aliyun.com");
  DefaultProfile::addEndpoint("cn-hangzhou", "cn-shanghai", "Bss",
                              "bss.aliyun.com");

  std::vector<Endpoint> endpoints =
      DefaultProfile::getProfile()->getEndpoints();
  for (auto& e : endpoints) {
    dumpEndpoint(e);
  }
}

void updateEndpointTest() {
  std::set<string> regions;

  std::vector<ProductDomain> productDomains;
  productDomains.push_back(ProductDomain("Ecs", "ecs.aliyun.com"));
  productDomains.push_back(ProductDomain("Rds", "rds.aliyun.com"));
  productDomains.push_back(ProductDomain("Oss", "oss.aliyun.com"));

  Endpoint endpoint("cn-hangzhou", regions, productDomains);

  dumpEndpoint(endpoint);
  DefaultProfile::updateEndpoint("cn-hangzhou", "Oss", "oss-admin.aliyun.com",
                                 &endpoint);
  dumpEndpoint(endpoint);
  assertTrue(endpoint.getName() == "cn-hangzhou");

  const ProductDomain* pd = DefaultProfile::findProductDomain(
      endpoint.getProductDomains(), "Oss");
  assertTrue(pd->getProductName() == "Oss");
  assertTrue(pd->getDomainName() == "oss-admin.aliyun.com");
}

void findEndpointTest() {
  DefaultProfile::addEndpoint("cn-hangzhou", "cn-hangzhou", "Ecs",
                              "ecs.aliyun.com");
  DefaultProfile::addEndpoint("cn-hangzhou", "cn-beijing", "Ecs",
                              "ecs.aliyun.com");
  DefaultProfile::addEndpoint("cn-hangzhou", "cn-shanghai", "Ecs",
                              "ecs.aliyun.com");

  Endpoint* endpoint = DefaultProfile::findEndpointByRegionId("cn-hangzhou");
  assertTrue(endpoint != NULL);
  assertTrue(endpoint->getName() == "cn-hangzhou");
}

int main() {
  testProfileCredential();
#if 0
  addToEndpointsTest();
  updateEndpointTest();
  findEndpointTest();
#endif
  addEndpointTest();
  return 0;
}

